package top.heue.utils.log

import top.heue.utils.log.base.IBaseHandler
import top.heue.utils.log.base.IBasePrinter
import top.heue.utils.log.handler.AnyHandler

object TaskPool : ITaskPool {
    private val handlers = mutableListOf<IBaseHandler<*>>()
    private val printers = mutableListOf<IBasePrinter>()
    private val anyHandler by lazy { AnyHandler() }

    override fun add(item: IBaseHandler<*>) {
        handlers.add(item)
        handlers.sortBy { it.priority }
    }

    override fun remove(item: IBaseHandler<*>) {
        handlers.remove(item)
    }

    override fun add(item: IBasePrinter) {
        printers.add(item)
    }

    override fun remove(item: IBasePrinter) {
        printers.remove(item)
    }

    override fun execute(logLevel: LogLevel, tag: String, vararg any: Any?) {
        val s = format(*any)
        print(logLevel, tag, s)
    }

    override fun format(vararg any: Any?): String = run {
        val ret = mutableListOf<String>()
        var hasNewline = false
        var index = 0
        val max = any.size
        val handlersSnapshot = handlers.toList()
        while (index < max) {
            val it = any[index]
            var out: String? = null
            for (handler in handlersSnapshot) {
                if (!handler.canHandle(it)) continue
                out = handler.execute(it)
                if (out != null) break
            }
            if (out == null) out = anyHandler.execute(it)!!
            if (out.contains('\n')) hasNewline = true
            ret.add(out)
            index++
        }
        if (ret.isEmpty()) return ""
        if (hasNewline) {
            return ret.joinToString("\n    ", "", "")
        }
        return ret.joinToString(" | ")
    }

    override fun print(logLevel: LogLevel, tag: String, string: String) {
        val printersSnapshot = printers.toList()
        printersSnapshot.forEach {
            it.execute(logLevel, tag, string)
        }
    }
}
